package com.tpp.threat_perception_platform.service.impl;

import com.alibaba.fastjson.JSON;
import com.github.pagehelper.PageHelper;
import com.github.pagehelper.PageInfo;
import com.tpp.threat_perception_platform.dao.HostMapper;
import com.tpp.threat_perception_platform.param.AssetsParam;
import com.tpp.threat_perception_platform.param.HotfixParam;
import com.tpp.threat_perception_platform.param.MyParam;
import com.tpp.threat_perception_platform.param.ThreatParam;
import com.tpp.threat_perception_platform.pojo.Account;
import com.tpp.threat_perception_platform.pojo.AppVulnerability;
import com.tpp.threat_perception_platform.pojo.Host;
import com.tpp.threat_perception_platform.response.ResponseResult;
import com.tpp.threat_perception_platform.service.*;

import com.tpp.threat_perception_platform.utils.EncryptionUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import java.sql.Timestamp;
import java.util.*;

@Service
public class HostServiceImpl implements HostService {
    @Autowired
    private HostMapper hostMapper;

    @Autowired
    private RabbitService rabbitService;

    @Autowired
    private AccountService accountService;

    @Autowired
    private AppVulnerabilityService appVulnerabilityService;

    @Autowired
    private VulService vulService;

    /*
     * @Description: 保存主机信息
     * @Param host
     * @return
     */
    @Override
    public int saveHost(Host host) {
    //先判断是否有Mac地址
        if(host.getMacAddress()==null||host.getMacAddress().equals("")){
            return 1;
        }
        //基本的逻辑：有主机的记录，更新；没有主机的记录，添加
        //怎么判断有没有主机的记录？？？
        //  通过mac地址判断
        Host dbhost =hostMapper.selectByMacAddress(host.getMacAddress());
        if(dbhost!=null){
            // 更新
            host.setId(dbhost.getId());
            host.setStatus(1);
            //时间
            host.setUpdateTime(new Timestamp(System.currentTimeMillis()));
            return hostMapper.updateByPrimaryKeySelective(host);
        }
        //组装队列名称 agent_[mac_address]_queue, mac_address需要去掉冒号
        String queueName = "agent_" + host.getMacAddress().replace(":", "") + "_queue";
        String routingKey = host.getMacAddress().replace(":", "");
        rabbitService.createAgentQueue("agent_exchange", queueName, routingKey);

        // 插入
        host.setStatus(1);
        host.setCreateTime(new Timestamp(System.currentTimeMillis()));
        return hostMapper.insertSelective(host);
    }
    @Override
    public ResponseResult<?> list() {
        return new ResponseResult<>(0,hostMapper.findAllOnlyWithMacAndHostname());
    }
    @Override
    public ResponseResult hostList(MyParam param) {

        // 设置分页参数
        PageHelper.startPage(param.getPage(), param.getLimit());
        // 查询所有
        List<Host> dataList = hostMapper.findAll(param);
        //如果当前时间-update_time > 4秒，则更新主机状态为0
        for (Host host : dataList) {
            Date updateTime = host.getUpdateTime();
            if (updateTime == null){
                host.setStatus(0);
                continue;
            }
            if (new Date().getTime() - updateTime.getTime() > 4000){
                host.setStatus(0);
            }
        }
        // 构架pageInfo
        PageInfo<Host> pageInfo = new PageInfo<>(dataList);

        return new ResponseResult<>(pageInfo.getTotal(), pageInfo.getList());

    }

    /**
     * 删除用户
     * @param ids
     * @return
     */
    @Override
    public ResponseResult delete(Integer[] ids) {
        hostMapper.delete(ids);
        return new ResponseResult<>(0, "删除成功！");
    }

    @Override
    public int updateHostByMacAddress(Host host) {
        //设置状态
        host.setStatus(1);
        //设置更新时间
        host.setUpdateTime(new Timestamp(System.currentTimeMillis()));
        return hostMapper.updateByMacAddress(host);
    }

    @Override
    public ResponseResult assetsDiscovery(AssetsParam param) {
        //验证探测的类型
        if(!param.getAccount().equals(0)&&!param.getAccount().equals(1)){
            return new ResponseResult(1004, "参数有误！");
        }
        //通过mac_address查询主机
        Host dbhost = hostMapper.selectByMacAddress(param.getMacAddress());
        //利用当前时间和更新时间判断主机是否在线
        if (dbhost == null || dbhost.getUpdateTime() == null || new Date().getTime() - dbhost.getUpdateTime().getTime() > 4000) {
            return new ResponseResult(1003, "主机不在线！");
        }
        //初始化探测类型
        param.setType("assets");
        //将param转换成JSON字符串
        String data = JSON.toJSONString(param);

        // 加密
        try {
            data = EncryptionUtils.encrypt(data);
        } catch (Exception e) {
            System.out.println("加密失败:" + e);
        }

        //组装队列的名字
        String routingKey = param.getMacAddress().replace(":", "");
        rabbitService.sendMessage("agent_exchange", routingKey, data);
        return new ResponseResult(0, "资产探测任务已下发！");
    }

    @Override
    public ResponseResult threatDiscovery(ThreatParam param) {
//        验证探测的类型
        // 参数空值检查
        if (param == null) {
            return new ResponseResult(1004, "参数有误！");
        }

        // 验证mac地址
        if (param.getMacAddress() == null || param.getMacAddress().isEmpty()) {
            return new ResponseResult(1004, "参数有误！");
        }
        if(!param.getApplication().equals(0)&&!param.getApplication().equals(1)){
            return new ResponseResult(1004, "参数有误！");
        }
        if(!param.getHotfix().equals(0)&&!param.getHotfix().equals(1)){
            return new ResponseResult(1004, "参数有误！");
        }
        if(!param.getSystem().equals(0)&&!param.getSystem().equals(1)){
            return new ResponseResult(1004, "参数有误！");
        }
        if(!param.getVulnerability().equals(0)&&!param.getVulnerability().equals(1)){
            return new ResponseResult(1004, "参数有误！");
        }
        if(!param.getWeakPassword().equals(0)&&!param.getWeakPassword().equals(1)){
            return new ResponseResult(1004, "参数有误！");
        }
        if(!isOnline(param.getMacAddress())){
            return new ResponseResult(1003, "主机不在线");
        }
        // 检查所有探测参数是否都为0
        if (param.getApplication().equals(0)&&param.getHotfix().equals(0)&&param.getSystem().equals(0)&&param.getVulnerability().equals(0)&&param.getWeakPassword().equals(0)) {
            return new ResponseResult(1005, "不需要进行探测");
        }

        // 查询
        List<Account> accounts = accountService.getAccountsByMacAddress(param.getMacAddress());

        List<Map<String, Object>> accountMaps = new ArrayList<>();
        for (Account account : accounts) {
            Map<String, Object> accountMap = new HashMap<>();
            accountMap.put("name", account.getName());
            accountMap.put("status", account.getStatus());
            // 可以根据需要添加更多字段
            accountMaps.add(accountMap);
        }
        param.setAccounts(accountMaps);

        List<Map<String, Object>> appVulnerabilities = appVulnerabilityService.getAllAppVulnerabilities();
        List<Map<String, Object>> camelCaseAppVulnerabilities = new ArrayList<>();

        // 将下划线格式的字段名转换为驼峰式
        for (Map<String, Object> appVulnerability : appVulnerabilities) {
            Map<String, Object> camelCaseMap = new HashMap<>();
            for (Map.Entry<String, Object> entry : appVulnerability.entrySet()) {
                String key = entry.getKey();
                String camelCaseKey = toCamelCase(key);
                camelCaseMap.put(camelCaseKey, entry.getValue());
            }
            camelCaseAppVulnerabilities.add(camelCaseMap);
        }

        param.setAppVulnerabilities(camelCaseAppVulnerabilities);

        List<Map<String, Object>> vulnerabilities = vulService.getAllVulnerabilities();
        List<Map<String, Object>> camelCaseVulnerabilities = new ArrayList<>();

        // 将下划线格式的字段名转换为驼峰式
        for (Map<String, Object> vulnerability : vulnerabilities) {
            Map<String, Object> camelCaseMap = new HashMap<>();
            for (Map.Entry<String, Object> entry : vulnerability.entrySet()) {
                String key = entry.getKey();
                String camelCaseKey = toCamelCase(key);
                camelCaseMap.put(camelCaseKey, entry.getValue());
            }
            camelCaseVulnerabilities.add(camelCaseMap);
        }

        param.setVulnerabilities(camelCaseVulnerabilities);


        //初始化探测类型
        param.setType("threat");

        //将param转换成JSON字符串
        String data = JSON.toJSONString(param);

        // 加密
        try {
            data = EncryptionUtils.encrypt(data);
        } catch (Exception e) {
            System.out.println("加密失败:" + e);
        }

        //组装队列的名字
        String routingKey = param.getMacAddress().replace(":", "");
        rabbitService.sendMessage("agent_exchange", routingKey, data);
        return new ResponseResult(0, "风险发现任务已下发！");
    }

    @Override
    public ResponseResult hotfixDiscovery(HotfixParam param) {
        //验证mac地址，type类型

        if(!isOnline(param.getMacAddress())){
            return new ResponseResult(1003, "主机不在线");
        }
//        初始化探测类型
        param.setType("hotfix");
        //将param转换成JSON字符串
        String data = JSON.toJSONString(param);
        //组装队列的名字

        String routingKey = param.getMacAddress().replace(":", "");
        rabbitService.sendMessage("agent_exchange",routingKey, data);
        return new ResponseResult(0, "补丁探测任务已下发，请稍后查看！");

    }
    // HostServiceImpl.java
    @Override
    public ResponseResult logSync(String macAddress) {
        // 通过 MAC 地址查询主机信息
        Host host = hostMapper.selectByMacAddress(macAddress);
        if (host == null) {
            return new ResponseResult(1001, "主机不存在！");
        }
        if(!isOnline(macAddress)){
            return new ResponseResult(1003, "主机不在线");
        }
        // 组装日志同步消息
        Map<String, Object> logSyncMessage = new HashMap<>();
        logSyncMessage.put("type", "logSync");
        logSyncMessage.put("macAddress", macAddress);
        String data = JSON.toJSONString(logSyncMessage);
        // 加密
        try {
            data = EncryptionUtils.encrypt(data);
        } catch (Exception e) {
            System.out.println("加密失败:" + e);
        }
        // 组装队列的名字
        String routingKey = macAddress.replace(":", "");
        rabbitService.sendMessage("agent_exchange", routingKey, data);
        return new ResponseResult(0, "日志同步任务已下发！");
    }

    @Override
    public ResponseResult updateLogSyncStatus(String macAddress, Integer status) {
        // 通过 MAC 地址查询主机信息
        Host host = hostMapper.selectByMacAddress(macAddress);
        if (host == null) {
            return new ResponseResult(1001, "主机不存在！");
        }
        if (!isOnline(macAddress)) {
            return new ResponseResult(1003, "主机不在线");
        }

        // 更新主机的日志同步状态
        host.setLogSyncStatus(status);
        host.setUpdateTime(new Timestamp(System.currentTimeMillis()));
        int result = hostMapper.updateSycByMacAddress(host);
        if (result <= 0) {
            return new ResponseResult(1002, "更新日志同步状态失败！");
        }

        // 组装日志同步消息
        Map<String, Object> logSyncMessage = new HashMap<>();
        logSyncMessage.put("type", "logSync");
        logSyncMessage.put("macAddress", macAddress);
        logSyncMessage.put("status", status);
        String data = JSON.toJSONString(logSyncMessage);

        // 加密
        try {
            data = EncryptionUtils.encrypt(data);
        } catch (Exception e) {
            System.out.println("加密失败:" + e);
            return new ResponseResult(1002, "加密失败！");
        }

        // 组装队列的名字
        String routingKey = macAddress.replace(":", "");
        rabbitService.sendMessage("agent_exchange", routingKey, data);
        return new ResponseResult(0, "日志同步状态已更新！");
    }



//
//    @Override
//    public ResponseResult sendLogSyncMessage(String macAddress, Integer status) {
//        // 组装日志同步消息
//        Map<String, Object> logSyncMessage = new HashMap<>();
//        logSyncMessage.put("type", "logSync");
//        logSyncMessage.put("macAddress", macAddress);
//        logSyncMessage.put("status", status);
//        String data = JSON.toJSONString(logSyncMessage);
//
//        // 加密
//        try {
//            data = EncryptionUtils.encrypt(data);
//        } catch (Exception e) {
//            System.out.println("加密失败:" + e);
//            return new ResponseResult(1, "加密失败");
//        }
//
//        // 组装队列的名字
//        String routingKey = macAddress.replace(":", "");
//        rabbitService.sendMessage("agent_exchange", routingKey, data);
//        return new ResponseResult(0, "日志同步消息已发送！");
//    }

    private Boolean isOnline(String macAddress){
        Host dbHost = hostMapper.selectByMacAddress(macAddress);
        if(dbHost==null||dbHost.getUpdateTime()==null||new Date().getTime()-dbHost.getUpdateTime().getTime()>4000){
            return false;
        }
        return true;
    }

    // 将下划线格式的字符串转换为驼峰式
    private String toCamelCase(String input) {
        StringBuilder result = new StringBuilder();
        boolean capitalizeNext = false;
        for (char c : input.toCharArray()) {
            if (c == '_') {
                capitalizeNext = true;
            } else {
                if (capitalizeNext) {
                    result.append(Character.toUpperCase(c));
                    capitalizeNext = false;
                } else {
                    result.append(c);
                }
            }
        }
        return result.toString();
    }
}
